//安装ArduinoMqttClient库和ArduinoJson库
//使用第三方库Adafruit/DHT sensor library

#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#include <ArduinoMqttClient.h>
#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_AVR_UNO_WIFI_REV2)
#include <WiFiNINA.h>
#elif defined(ARDUINO_SAMD_MKR1000)
#include <WiFi101.h>
#elif defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h>
#elif defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_GIGA) || defined(ARDUINO_OPTA)
#include <WiFi.h>
#elif defined(ARDUINO_PORTENTA_C33)
#include <WiFiC3.h>
#elif defined(ARDUINO_UNOR4_WIFI)
#include <WiFiS3.h>
#endif

#include <ArduinoJson.h>

void onMqttMessage(int messageSize);

#define DHTPIN D4
#define LED_PIN D3

#define DHTTYPE DHT11 // DHT 11
// #define DHTTYPE    DHT22     // DHT 22 (AM2302)
// #define DHTTYPE    DHT21     // DHT 21 (AM2301)
DHT_Unified dht(DHTPIN, DHTTYPE);

uint32_t delayMS;

char ssid[] = "dayuan";
char pass[] = "19900625";

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

const char broker[] = "a1elxec77tP.iot-as-mqtt.cn-shanghai.aliyuncs.com";
int port = 1883;

const char inTopic[] = "/sys/a1elxec77tP/esp8266_dev/thing/service/property/set";
const char outTopic[] = "/sys/a1elxec77tP/esp8266_dev/thing/event/property/post";

const char clientID[] = "a1elxec77tP.esp8266_dev|securemode=2,signmethod=hmacsha256,timestamp=1743600073262|";
const char username[] = "esp8266_dev&a1elxec77tP";
const char password[] = "f5271ef29b36af26f19d2c53bbaf472938d7399a5665382b8d64f05badef3be1";

const long interval = 10000;
unsigned long previousMillis = 0;

int count = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(LED_PIN,OUTPUT);

  while (WiFi.begin(ssid, pass) != WL_CONNECTED)
  {
    Serial.print(".");
    delay(5000);
  }
  mqttClient.setId(clientID);
  mqttClient.setUsernamePassword(username, password);
  if (!mqttClient.connect(broker, port))
  {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());

    while (1)
      ;
  }
  Serial.println("You're connected to the MQTT broker!");
  Serial.println();

  // set the message receive callback
  mqttClient.onMessage(onMqttMessage);

  int subscribeQos = 1;

  mqttClient.subscribe(inTopic, subscribeQos);

  // dht设置初始化
  dht.begin();
  sensor_t sensor;
  // 获取温度
  dht.temperature().getSensor(&sensor);

  // 获取湿度
  dht.humidity().getSensor(&sensor);
  delayMS = sensor.min_delay / 1000;

}

void loop()
{

  mqttClient.poll();
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;
    String payload;

    //{"params":{"temperature":"30.1","Humidity":"60"},"version":"1.0.1"}
    DynamicJsonDocument json_msg(512);
    DynamicJsonDocument json_data(512);

    sensors_event_t event;
    dht.temperature().getEvent(&event);
    if (isnan(event.temperature))
    {
      Serial.println(F("Error reading temperature!"));
      json_data["temperature"] = "0";
    }
    else
    {
      json_data["temperature"] = event.temperature;
    }

    dht.humidity().getEvent(&event);
    if (isnan(event.relative_humidity))
    {
      Serial.println(F("Error reading humidity!"));
      json_data["Humidity"] = "0";
    }
    else
    {
      json_data["Humidity"] = event.relative_humidity;
    }

    json_data["Led"] = digitalRead(LED_PIN);
    
    json_msg["params"] = json_data;
    json_msg["version"] = "1.0.1";

    serializeJson(json_msg, payload);

    Serial.print("Sending message to topic: ");
    Serial.println(outTopic);
    Serial.println(payload);

    bool retained = false;
    int qos = 1;
    bool dup = false;

    mqttClient.beginMessage(outTopic, payload.length(), retained, qos, dup);
    mqttClient.print(payload);
    mqttClient.endMessage();
    Serial.println();
    count++;
  }
}

void onMqttMessage(int messageSize)
{
  // we received a message, print out the topic and contents
  Serial.print("Received a message with topic '");
  Serial.print(mqttClient.messageTopic());
  Serial.print("', duplicate = ");
  Serial.print(mqttClient.messageDup() ? "true" : "false");
  Serial.print(", QoS = ");
  Serial.print(mqttClient.messageQoS());
  Serial.print(", retained = ");
  Serial.print(mqttClient.messageRetain() ? "true" : "false");
  Serial.print("', length ");
  Serial.print(messageSize);
  Serial.println(" bytes:");

  // {"method":"thing.service.property.set","id":"1120777540","params":{"Humidity":3,"temperature":2,"Led":1},"version":"1.0.0"}
  String inputString;
  while (mqttClient.available())
  {
    char ch = (char)mqttClient.read();
    inputString += ch;
    //Serial.print((char)mqttClient.read());

    if(inputString.length() == messageSize){
      Serial.print(inputString);
      JsonDocument doc;
      DeserializationError error = deserializeJson(doc, inputString);
      int state = doc["params"]["Led"];
      Serial.print(state);
      if(state == 0){
        digitalWrite(LED_PIN,LOW);
      }else{
        digitalWrite(LED_PIN,HIGH);
      }

    }
  }
  Serial.println();

  Serial.println();
}